﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Aphysoft.Vate.Graphics
{
    public static class ProjectorManager
    {
        #region Constants

        public const string DefaultProjectorName = "DefaultProjector";

        #endregion

        #region Properties

        /// <summary>
        /// Other projectors.
        /// </summary>
        private static Dictionary<string, Projector> projectors;
        /// <summary>
        /// Gets projector collection.
        /// </summary>
        public static Dictionary<string, Projector> Projectors
        {
            get { return projectors; }
        }
        /// <summary>
        /// Default projector.
        /// </summary>
        private static Projector defaultProjector = null;
        /// <summary>
        /// Gets default projector.
        /// </summary>
        public static Projector DefaultProjector
        {
            get { return defaultProjector; }
        }
        /// <summary>
        /// Current projector name.
        /// </summary>
        private static string current = string.Empty;
        /// <summary>
        /// Current projector name.
        /// </summary>
        public static string Current
        {
            get { return current; }
            set { current = value; }
        }
        /// <summary>
        /// Gets current game projector instance. Only available in GameDraw.
        /// </summary>
        public static Projector CurrentProjector
        {
            get 
            {
                if (current.Equals(string.Empty))
                    return null;
                else
                    return Find(current); 
            }
        }
        /// <summary>
        /// True if ProjectorManager has been inited; otherwise, false.
        /// </summary>
        private static bool inited = false;
        #endregion

        #region Initiator
        /// <summary>
        /// Initializes ProjectorManager.
        /// </summary>
        public static void Init()
        {
            if (inited)
                throw new Exception("ProjectorManager has been initialized.");
            else
                inited = true;

            projectors = new Dictionary<string, Projector>();

            // create an entry as default projector
            defaultProjector = new Projector(0, 0, 100, 100);
            defaultProjector.Camera = CameraManager.DefaultCamera;
#if DEBUG
            Debug.Write("ProjectorManager Initialized.");
#endif
        }

        #endregion

        #region Methods

        #region Graphics

        /// <summary>
        /// Begins Projector Render. Internal use only.
        /// </summary>
        public static void Begin()
        {
            current = DefaultProjectorName;
            Vate.Device.Viewport = Vate.DefaultViewport;
        }
        /// <summary>
        /// End Projector Render. Internal use only.
        /// </summary>
        public static void End()
        {
            Vate.Device.Viewport = Vate.DefaultViewport;
            current = string.Empty;
        }

        #endregion

        /// <summary>
        /// Add a Projector to projector manager.
        /// </summary>
        /// <param name="name">The name of projector</param>
        /// <param name="xPercentage">Percentage 0-100 position X on screen</param>
        /// <param name="yPercentage">Percentage 0-100 position Y on screen</param>
        /// <param name="widthPercentage">Percentage 0-100 projector width</param>
        /// <param name="heightPercentage">Percentage 0-100 projector height</param>
        public static Projector Add(string name, float xPercentage, float yPercentage, float widthPercentage, float heightPercentage)
        {
            Projector existingProjector = Find(name);

            if (existingProjector == null)
            {
                Projector newProjector = new Projector(xPercentage, yPercentage, widthPercentage, heightPercentage);
                projectors.Add(name, newProjector);

                // set projector camera to default camera.
                newProjector.Camera = CameraManager.DefaultCamera;

                Debug.Write(StringHelper.Create("New Projector \"", name, "\" added."));

                return newProjector;
            }
            else
                return existingProjector;
        }
        /// <summary>
        /// Remove Projector specified by its name. Returns true if succeeded.
        /// </summary>
        /// <param name="name">The name of projector</param>
        public static bool Remove(string name)
        {
            if (projectors.ContainsKey(name))
            {
                projectors.Remove(name);
                return true;
            }
            else
                return false;
        }
        /// <summary>
        /// Gets a reference to Projector instance specified by name.
        /// </summary>
        /// <param name="name">The name of Projector.</param>
        /// <returns></returns>
        public static Projector Find(string name)
        {
            if (name.Equals(DefaultProjectorName))
                return DefaultProjector;
            else if (projectors.ContainsKey(name))
                return projectors[name];
            else
                return null;
        }

        #endregion
    }
}
